package common

import (
	"errors"
	"fmt"
	"net/http"
	"raymond/api/bnb"
	"raymond/result"
	"raymond/util"

	"github.com/labstack/echo/v4"
)

type GetCoinBalanceVO struct {
	Account string `json:"account" validate:"required,min=40,max=42"`
	Amount  string `json:"amount,omitempty"`
}

type GetERC20BalanceVO struct {
	ContractAddress string `json:"contract" validate:"required,min=40,max=42"`
	ContractDecimal int    `json:"decimal,omitempty"`
	Account         string `json:"account" validate:"required,gt=0"`

	Amount string `json:"amount,omitempty"`
}

func GetCoinBalanceAPI(c echo.Context) error {
	vo := new(GetCoinBalanceVO)
	if err := c.Bind(vo); err != nil {
		return err
	}
	if err := c.Validate(vo); err != nil {
		return err
	}
	isValidAddress := util.IsValidAddress(vo.Account)
	if isValidAddress {
		isContract, err := util.IsContractAddress(vo.Account)
		if err != nil {
			return err
		}
		if isContract {
			return errors.New(result.Message[result.IS_CONTRACT_ADDRESS])
		}
	}
	amt, err := bnb.GetBNBCoinBalance(vo.Account)
	if err != nil {
		return errors.New(err.Error())
	}
	vo.Amount = fmt.Sprintf("%f", amt)
	return c.JSON(
		http.StatusOK,
		result.Ok(vo),
	)
}

func GetTokenBalanceAPI(c echo.Context) error {
	vo := new(GetERC20BalanceVO)
	if err := c.Bind(vo); err != nil {
		return err
	}
	if err := c.Validate(vo); err != nil {
		return err
	}
	isValidContractAddr := util.IsValidAddress(vo.ContractAddress)
	if isValidContractAddr {
		isContract, err := util.IsContractAddress(vo.ContractAddress)
		if err != nil {
			return err
		}
		if !isContract {
			return errors.New(result.Message[result.NOT_CONTRACT_ADDRESS])
		}
	}
	isValidAddress := util.IsValidAddress(vo.Account)
	if isValidAddress {
		isContract, err := util.IsContractAddress(vo.Account)
		if err != nil {
			return err
		}
		if isContract {
			return errors.New(result.Message[result.IS_CONTRACT_ADDRESS])
		}
	}
	amt, err := bnb.GetBEP20Balance(vo.ContractAddress, vo.Account)
	if err != nil {
		return errors.New(err.Error())
	}
	vo.Amount = fmt.Sprintf("%f", amt)
	return c.JSON(
		http.StatusOK,
		result.Ok(vo),
	)
}
